// Dedicated to the public domain by Christopher Diggins
// http://www.cdiggins.com

#ifndef YARD_CAT_GRAMMAR_HPP
#define YARD_CAT_GRAMMAR_HPP

#include "yard_shared_grammar.hpp"

namespace cat_grammar
{
    using namespace shared_grammar;
	
	struct Instruction; 
	struct DefName;
	struct DefBody;

	struct QuotedExpr
		: Star<Instruction> { };

	struct Quotation
		: NoFailSeq<CharTok<'['>, Store<QuotedExpr>, CharTok<']'> > { };

	struct Operation
		: Seq<Ident, Opt<NoFailSeq<CharTok<'$'>, Plus<Digit> > > > { };

	struct Instruction
		: Or<Literal, Quotation, Seq<Store<Operation>, WS> >  { };

	struct Arg
		: AlphaName { };

	struct ArgList 
		: NoFailSeq<CharTok<'('>, Store<Arg>, CharTok<')'> > { };

	struct LocalDef
		: NoFailSeq<DEFINE, Store<DefName>, Store<DefBody> > { }; 

	struct DefName 
		: Name { };

	struct DefBody 
		: Seq<Opt<ArgList>, Star<Store<LocalDef> >, CharTok<'{'>, Star<Instruction>, CharTok<'}'> > { };

	struct Def
		: NoFailSeq<DEFINE, Store<DefName>, Store<DefBody> > { };

	struct Expr
		: Star<Instruction> { };

	struct Program
		: Star<Def> { };
}

#endif
